using System;
using System.Data;
using System.Configuration;
using Pheonix.Fashionzoomer.DAL;
using System.Data.SqlClient;
using System.Collections;
using Pheonix.CodeLibrary.Data;
using Pheonix.CodeLibrary;

/// <summary>
/// Summary description for Message
/// </summary>

namespace Pheonix.Fashionzoomer.Entity.SqlServer2000
{
    [System.ComponentModel.DataObject]
    public class Message : SqlServerDAO
    {
        #region Message Private Fields

		private Int32 _id;
		private Int32 _senderUserId;
		private Int32 _receiverUserId;
		private String _messageBody;
		private DateTime _whenSent;
		private Boolean _isRead;
		private Int32 _parentMessageId;

        #endregion

        #region Message Constractors

		public Message(){}

		public Message
		(
			Int32 id,
			Int32 senderUserId,
			Int32 receiverUserId,
			String messageBody,
			DateTime whenSent,
			Boolean isRead,
			Int32 parentMessageId

		)
		{
			this._id = id;
			this._senderUserId = senderUserId;
			this._receiverUserId = receiverUserId;
			this._messageBody = messageBody;
			this._whenSent = whenSent;
			this._isRead = isRead;
			this._parentMessageId = parentMessageId;
		}

        #endregion

        #region Message Properties

		public Int32 Id
		{
			get{ return this._id; }
			set{ this._id = value; }
		}

		public Int32 SenderUserId
		{
			get{ return this._senderUserId; }
			set{ this._senderUserId = value; }
		}

		public Int32 ReceiverUserId
		{
			get{ return this._receiverUserId; }
			set{ this._receiverUserId = value; }
		}

		public String MessageBody
		{
			get{ return this._messageBody; }
			set{ this._messageBody = value; }
		}

		public DateTime WhenSent
		{
			get{ return this._whenSent; }
			set{ this._whenSent = value; }
		}

		public Boolean IsRead
		{
			get{ return this._isRead; }
			set{ this._isRead = value; }
		}

		public Int32 ParentMessageId
		{
			get{ return this._parentMessageId; }
			set{ this._parentMessageId = value; }
		}


        #endregion

        #region Message Static Methods

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)]
        public static Int32 CreateNewMessage
        (
			Int32 senderUserId,
			Int32 receiverUserId,
			String messageBody,
			DateTime whenSent,
			Boolean isRead,
			Int32 parentMessageId

        )
        {
            //creating an empty Message object
            Message message = new Message();
            message.SenderUserId = senderUserId;
			message.ReceiverUserId = receiverUserId;
			message.MessageBody = messageBody;
			message.WhenSent = whenSent;
			message.IsRead = isRead;
			message.ParentMessageId = parentMessageId;

            return Message.CreateNewMessage(message);
        }

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
        public static bool UpdateMessage
        (
			Int32 id,
			Int32 senderUserId,
			Int32 receiverUserId,
			String messageBody,
			DateTime whenSent,
			Boolean isRead,
			Int32 parentMessageId

        )
        {
            Message message = Message.GetMessageById(id);
            message.SenderUserId = senderUserId;
			message.ReceiverUserId = receiverUserId;
			message.MessageBody = messageBody;
			message.WhenSent = whenSent;
			message.IsRead = isRead;
			message.ParentMessageId = parentMessageId;

            return Message.UpdateMessage(message);
        }

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
        public static bool DeleteMessage
        (
            Int32 id
        )
        {
            //Validate Input
            if (id <= GetIdMinValue)
                throw (new ArgumentOutOfRangeException("id in Message"));

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddParameterToSqlCmd(sqlCmd, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, id);
            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_DELETEMESSAGE);
            GetOneData(sqlCmd);
            int returnValue = (int)sqlCmd.Parameters["@ReturnValue"].Value;
            return (returnValue == 0 ? false : true);

        }

        public static bool DeleteMessageList(System.Collections.Generic.List<Int32> idListToDelete)
        {
            //Validate Input
            foreach (Int32 id in idListToDelete)
                if (id <= GetIdMinValue)
                    throw (new ArgumentOutOfRangeException("id in Message"));

            //performing deletion operation //

            string csvString = Utility.MakeCSV(idListToDelete);

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddParameterToSqlCmd(sqlCmd, "@IdList", SqlDbType.NVarChar, csvString.Length, 
                ParameterDirection.Input, csvString);
            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_DELETEMESSAGELIST);
            GetOneData(sqlCmd);
            int returnValue = (int)sqlCmd.Parameters["@ReturnValue"].Value;
            return (returnValue == idListToDelete.Count ? true : false);
        }
		
		[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
		public static CustomCollection<Message> GetMessageBySenderUserId(Int32 senderUserId)
		{
			if(senderUserId <= GetIdMinValue)
				throw (new ArgumentOutOfRangeException("senderUserId in Message"));

			SqlCommand sqlCmd = new SqlCommand();
			AddParameterToSqlCmd(sqlCmd, "@SenderUserId", SqlDbType.Int, 0, ParameterDirection.Input, senderUserId);
			SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETMESSAGEBYSENDERUSERID);
			GenerateCollectionFromReader dg = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
			CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, dg));

			if (objCollection.Count > 0)
				return objCollection;
			else
				return null;
		}

		[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
		public static CustomCollection<Message> GetMessageByReceiverUserId(Int32 receiverUserId)
		{
			if(receiverUserId <= GetIdMinValue)
				throw (new ArgumentOutOfRangeException("receiverUserId in Message"));

			SqlCommand sqlCmd = new SqlCommand();
			AddParameterToSqlCmd(sqlCmd, "@ReceiverUserId", SqlDbType.Int, 0, ParameterDirection.Input, receiverUserId);
			SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETMESSAGEBYRECEIVERUSERID);
			GenerateCollectionFromReader dg = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
			CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, dg));

			if (objCollection.Count > 0)
				return objCollection;
			else
				return null;
		}

		[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
		public static CustomCollection<Message> GetMessageByParentMessageId(Int32 parentMessageId)
		{
			if(parentMessageId <= GetIdMinValue)
				throw (new ArgumentOutOfRangeException("parentMessageId in Message"));

			SqlCommand sqlCmd = new SqlCommand();
			AddParameterToSqlCmd(sqlCmd, "@ParentMessageId", SqlDbType.Int, 0, ParameterDirection.Input, parentMessageId);
			SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETMESSAGEBYPARENTMESSAGEID);
			GenerateCollectionFromReader dg = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
			CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, dg));

			if (objCollection.Count > 0)
				return objCollection;
			else
				return null;
		}

        #endregion

        #region Message Instance Methods
        
        public bool Save()
		{
			if(Id <= GetIdMinValue)
			{
				Int32 TempId=CreateNewMessage(this);
				if(TempId>0)
				{
					_id=TempId;
					return true;
				}
				else
				{
					// error occurs
					return false;
				}
			}
			else
			{	//This is a update Command
				return (UpdateMessage(this));
			}
		}

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
        public static CustomCollection<Message> GetAllMessage()
        {
            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETALLMESSAGE);
            GenerateCollectionFromReader result = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
            CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, result));

            return objCollection;
        }

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
        public static CustomCollection<Message> GetAllMessagePaged(String orderBy, Int32 startRowIndex, Int32 maximumRows)
        {
            //Validate Input
            if (orderBy == "")
                orderBy = "Id";

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@orderby", SqlDbType.VarChar, 50, ParameterDirection.Input, orderBy);
            AddParameterToSqlCmd(sqlCmd, "@startRowIndex", SqlDbType.Int, 0, ParameterDirection.Input, startRowIndex);
            AddParameterToSqlCmd(sqlCmd, "@maximumRows", SqlDbType.Int, 0, ParameterDirection.Input, maximumRows);

            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETALLMESSAGEPAGED);

            GenerateCollectionFromReader result = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
            CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, result));
            return objCollection;
        }

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
        public static int GetAllMessagePagedCount(String orderBy, Int32 startRowIndex, Int32 maximumRows)
        {
            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();

            AddParameterToSqlCmd(sqlCmd, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETALLMESSAGEPAGEDCOUNT);
            GetOneData(sqlCmd);

            int returnValue = (int)sqlCmd.Parameters["@ReturnValue"].Value;
            return returnValue;
        }

        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
        public static Message GetMessageById(Int32 id)
        {
            if (id <= GetIdMinValue)
                throw (new ArgumentOutOfRangeException("id in Message"));

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, id);
            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_GETMESSAGEBYID);
            GenerateCollectionFromReader result = new GenerateCollectionFromReader(GenerateMessageCollectionFromReader);
            CustomCollection<Message> objCollection = ((CustomCollection<Message>)GetAllData(sqlCmd, result));

            if (objCollection.Count > 0)
                return (Message)objCollection[0];
            else
                return null;
        }

        public static Int32 CreateNewMessage(Message newMessage)
        {
            // validate Parameters
            if (newMessage == null)
                throw (new ArgumentNullException("newMessage in Message"));

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);

            AddParameterToSqlCmd(sqlCmd, "@SenderUserId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.SenderUserId);
			AddParameterToSqlCmd(sqlCmd, "@ReceiverUserId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.ReceiverUserId);
			AddParameterToSqlCmd(sqlCmd, "@MessageBody", SqlDbType.NText, 0, ParameterDirection.Input, newMessage.MessageBody);
			AddParameterToSqlCmd(sqlCmd, "@WhenSent", SqlDbType.DateTime, 0, ParameterDirection.Input, newMessage.WhenSent);
			AddParameterToSqlCmd(sqlCmd, "@IsRead", SqlDbType.Bit , 0, ParameterDirection.Input, newMessage.IsRead);
			AddParameterToSqlCmd(sqlCmd, "@ParentMessageId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.ParentMessageId);

            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_CREATENEWMESSAGE);
            GetOneData(sqlCmd);
            return ((Int32)sqlCmd.Parameters["@ReturnValue"].Value);

        }

        public static bool UpdateMessage(Message newMessage)
        {
            // validate Parameters
            if (newMessage == null)
                throw (new ArgumentNullException("newMessage"));

            // Execute SQL Command
            SqlCommand sqlCmd = new SqlCommand();
            AddParameterToSqlCmd(sqlCmd, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);

            AddParameterToSqlCmd(sqlCmd, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.Id);
            AddParameterToSqlCmd(sqlCmd, "@SenderUserId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.SenderUserId);
			AddParameterToSqlCmd(sqlCmd, "@ReceiverUserId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.ReceiverUserId);
			AddParameterToSqlCmd(sqlCmd, "@MessageBody", SqlDbType.NText, 0, ParameterDirection.Input, newMessage.MessageBody);
			AddParameterToSqlCmd(sqlCmd, "@WhenSent", SqlDbType.DateTime, 0, ParameterDirection.Input, newMessage.WhenSent);
			AddParameterToSqlCmd(sqlCmd, "@IsRead", SqlDbType.Bit , 0, ParameterDirection.Input, newMessage.IsRead);
			AddParameterToSqlCmd(sqlCmd, "@ParentMessageId", SqlDbType.Int, 0, ParameterDirection.Input, newMessage.ParentMessageId);

            SetCommandType(sqlCmd, CommandType.StoredProcedure, SPR_MESSAGE_UPDATEMESSAGE);
            GetOneData(sqlCmd);
            int returnValue = (int)sqlCmd.Parameters["@ReturnValue"].Value;
            return (returnValue == 0 ? false : true);
        }

        #endregion

        #region Message Related Collections
        /// <summary>
        /// Creates and returns a strongly typed collection of Message custom entity. 
        /// The colelction is created through iterating on the IdataReader object which contains 
        /// Message information, as a set of records, similar to tabular format.
        /// </summary>
        public static IList GenerateMessageCollectionFromReader(IDataReader returnData)
        {

            //creating the instance of Message collection
            CustomCollection<Message> colMessage = new CustomCollection<Message>();

            //Iterating thriugh the data reader, to generate Message collection.

            //getting the Message collection by iterating thru the data reader
            while (returnData.Read())
            {
                //passing the Message constructor parameters from the current instance of data reader fields.
                Message newMessage = new Message
                (
                    returnData["id"] == System.DBNull.Value ? GetIdMinValue : (Int32)returnData["id"],
                    returnData["sender_user_id"] == System.DBNull.Value ? Int32.MinValue : (Int32)returnData["sender_user_id"],
					returnData["receiver_user_id"] == System.DBNull.Value ? Int32.MinValue : (Int32)returnData["receiver_user_id"],
					returnData["message_body"] == System.DBNull.Value ? String.Empty : (String)returnData["message_body"],
					returnData["when_sent"] == System.DBNull.Value ? DateTime.MinValue : (DateTime)returnData["when_sent"],
					returnData["is_read"] == System.DBNull.Value ? false : (Boolean)returnData["is_read"],
					returnData["parent_message_id"] == System.DBNull.Value ? Int32.MinValue : (Int32)returnData["parent_message_id"]

                );
                //adding the Message to the collection
                colMessage.Add(newMessage);
            }

            //returns the collection of Message 
            return (colMessage);
        }

        #endregion

        #region Constants and Default Values

        public static Int32 GetIdMinValue
        {
            get
            {
                return 0;
            }
        }

        //contants
        internal const string SPR_MESSAGE_CREATENEWMESSAGE = "spr_Message_CreateNewMessage";
        internal const string SPR_MESSAGE_UPDATEMESSAGE = "spr_Message_UpdateMessage";
        internal const string SPR_MESSAGE_DELETEMESSAGE = "spr_Message_DeleteMessage";
        internal const string SPR_MESSAGE_DELETEMESSAGELIST = "spr_Message_DeleteMessageList";
        internal const string SPR_MESSAGE_GETMESSAGEBYID = "spr_Message_GetMessageById";
        internal const string SPR_MESSAGE_GETALLMESSAGE = "spr_Message_GetAllMessage";
        internal const string SPR_MESSAGE_GETALLMESSAGEPAGED = "spr_Message_GetAllMessagePaged";
        internal const string SPR_MESSAGE_GETALLMESSAGEPAGEDCOUNT = "spr_Message_GetAllMessagePagedCount";

		//Foreign key contants
		internal const string SPR_MESSAGE_GETMESSAGEBYSENDERUSERID="spr_Message_GetMessageBySenderUserId";
		internal const string SPR_MESSAGE_GETMESSAGEBYSENDERUSERIDPAGED="spr_Message_GetMessageBySenderUserIdPaged";
		internal const string SPR_MESSAGE_GETMESSAGEBYSENDERUSERIDPAGEDCOUNT="spr_Message_GetMessageBySenderUserIdPagedCount";
		internal const string SPR_MESSAGE_GETMESSAGEBYRECEIVERUSERID="spr_Message_GetMessageByReceiverUserId";
		internal const string SPR_MESSAGE_GETMESSAGEBYRECEIVERUSERIDPAGED="spr_Message_GetMessageByReceiverUserIdPaged";
		internal const string SPR_MESSAGE_GETMESSAGEBYRECEIVERUSERIDPAGEDCOUNT="spr_Message_GetMessageByReceiverUserIdPagedCount";
		internal const string SPR_MESSAGE_GETMESSAGEBYPARENTMESSAGEID="spr_Message_GetMessageByParentMessageId";
		internal const string SPR_MESSAGE_GETMESSAGEBYPARENTMESSAGEIDPAGED="spr_Message_GetMessageByParentMessageIdPaged";
		internal const string SPR_MESSAGE_GETMESSAGEBYPARENTMESSAGEIDPAGEDCOUNT="spr_Message_GetMessageByParentMessageIdPagedCount";
		
        #endregion
    }
}
